﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ComputerGraphics.Graphics;

namespace ComputerGraphics.Geometry
{
    public class Sphere : Shape
    {
        private Point3D center;
        private double radius;
        private double sqrRadius;

        public Sphere(Point3D center, double radius, Texture texture) : base(texture)
        {
            this.center = center;
            this.radius = radius;
            this.sqrRadius = radius * radius;
        }

        public override Intersection Intersect(Ray ray)
        {
            Intersection ret = null;
            Point3D v = center - ray.Origin;
            double a0 = v.SquareNorm - sqrRadius;
            double dDotv = ray.Direction * v;

            if (dDotv >= 0)
            {
                double discr = dDotv * dDotv - a0;

                if (discr >= 0)
                {
                    double dist = dDotv - Math.Sqrt(discr);
                    Point3D position = ray.GetPointByDistance(dist);
                    Point3D normal = (position - center).Direction;

                    ret = new Intersection(ray, this, dist, position, normal);
                }
            }

            return ret;
        }

        public override Intersection InternalIntersect(Ray ray)
        {
            Point3D n = ray.Origin - center;
            Point3D position = center + n + ray.Direction * (-2 * n * ray.Direction); //TODO Improve this
            double dist = (position - position.Direction).Norm;
            Point3D normal = (center - position).Direction;

            return new Intersection(ray, this, dist, position, normal);
        }

        public double Radius
        {
            get { return radius; }
        }

        public double SqrRadius
        {
            get { return radius * radius; }
        }

        public Point3D Center
        {
            get { return center; }
        }
    }
}
